<?php 
// +----------------------------------------------------------------------
// | RXThinkCMF_EVTP5.1_PRO前后端分离旗舰版框架 [ RXThinkCMF ]
// +----------------------------------------------------------------------
// | 版权所有 2018~2021 南京RXThinkCMF研发中心
// +----------------------------------------------------------------------
// | 官方网站: http://www.rxthink.cn
// +----------------------------------------------------------------------
// | 作者: 牧羊人 <rxthinkcmf@163.com>
// +----------------------------------------------------------------------
// | 免责声明:
// | 本软件框架禁止任何单位和个人用于任何违法、侵害他人合法利益等恶意的行为，禁止用于任何违
// | 反我国法律法规的一切平台研发，任何单位和个人使用本软件框架用于产品研发而产生的任何意外
// | 、疏忽、合约毁坏、诽谤、版权或知识产权侵犯及其造成的损失 (包括但不限于直接、间接、附带
// | 或衍生的损失等)，本团队不承担任何法律责任。本软件框架只能用于公司和个人内部的法律所允
// | 许的合法合规的软件产品研发，详细声明内容请阅读《框架免责声明》附件；
// +----------------------------------------------------------------------

namespace app\admin\service;


use app\admin\model\AttentionFactor;
use app\admin\model\AttentionSetting;
use app\admin\model\AttentionUser;
use app\admin\model\AttentionUserData;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Style\Font;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use think\Exception;

/**
 * 专注力测评用户管理-服务类
 * @author 牧羊人
 * @since: 2024/02/26
 * Class AttentionUserService
 * @package app\admin\service
 */
class AttentionuserService extends BaseService
{
    /**
     * 构造函数
     * LevelService constructor.
     */
    protected $userDataModel = null;
    protected $settingModel = null;
    protected $factorModel = null;
    public function __construct()
    {
        $this->model = new AttentionUser();
        $this->userDataModel = new AttentionUserData();
        $this->settingModel = new AttentionSetting();
        $this->factorModel = new AttentionFactor();
    }
	
	/**
     * 获取数据列表
     * @return array
     * @since 2024/02/26
     * @author 牧羊人
     */
    public function getList()
    {
        $param = request()->param();

        // 查询条件
        $map = [];
		
	
	    // 姓名
        $name = isset($param['name']) ? trim($param['name']) : '';
        if ($name) {
            $map[] = ['name', 'like', "%{$name}%"];
        }
		
	    // 性别
        $gender = isset($param['gender']) ? (int)$param['gender'] : 0;
        if ($gender) {
            $map[] = ['gender', '=', $gender];
        }

        // 联系方式
        $phone = isset($param['phone']) ? trim($param['phone']) : '';
        if ($phone) {
            $map[] = ['phone', 'like', "%{$phone}%"];
        }
        return parent::getList($map); // TODO: Change the autogenerated stub
    }


    public function getResult()
    {
        $param = request()->param();
        $userId = getter($param, 'user_id', '');
        if (empty($userId)) throw new Exception('参数错误');

        $answers = $this->userDataModel->where('user_id', $userId)->select();
        if (empty($answers[0])) {
            return message("未完成问卷", false);
        }
        $answerScore = [];
        foreach ($answers as $k => $answer) {
            $answerScore[] = $answer['answer_score'];
        }
        $totalScore = array_sum($answerScore);

        $setting = $this->settingModel->getInfo(1);
        $unusual = $totalScore >= $setting['warning_score'];


        $factors = $this->factorModel->where('mark', 1)->order('weight', 'desc')->select();
        $data = [];
        foreach ($factors as $factor) {
            $calcRule = json_decode($factor['calc_rule'], true);
            $factorAnswerScore = $this->calcScoreByFactor($answers, $factor['id']);
            $result = $this->calcResultByFactorScore($factorAnswerScore, $calcRule);
            $data[] = [
                'id' => $factor['id'],
                'title' => $factor['title'],
                'tips' => $factor['tips'],
                'desc' => $factor['desc'],
                'score' => $factorAnswerScore,
                'result' => $result['result'],
                'result_desc' => $result['desc']
            ];
        }


        $result = [
            'total_score' => $totalScore,
            'is_unusual' => $unusual,
            'warning_text' => $setting['warning_text'],
            'data' => $data
        ];
        return message("操作成功", true, $result);
    }

    private function calcScoreByFactor($answers, $factorId)
    {
        $scores = [];
        if (!empty($answers)) {
            foreach ($answers as $answer) {
                if ($answer['question_type'] == $factorId) {
                    $scores[] = $answer['answer_score'];
                }
            }
        }
        return array_sum($scores);
    }

    private function calcResultByFactorScore($score, $rule)
    {
        foreach ($rule as $item) {
            if ($score >= $item['min'] && $score <= $item['max']) {
                return $item;
                break;
            }
        }
        return [];
    }

    public function getAnswers()
    {
        $param = request()->param();
        $userId = getter($param, 'user_id', '');
        if (empty($userId)) throw new Exception('参数错误');

        $answers = $this->userDataModel->where('user_id', $userId)->select();
        if (empty($answers[0])) {
            return message("未完成问卷", false);
        }

        foreach ($answers as &$answer) {
            $factor = $this->factorModel->find($answer['question_type']);
            $answer['factor'] = $factor['title'] ?? '';
        }

        return message('查询成功', true, $answers);
    }

    public function dump()
    {
        $param = request()->param();
        $userId = getter($param, 'user_id', '');
        if (empty($userId)) throw new Exception('参数错误');

        // 用户信息
        $userInfo = $this->model->find($userId);

        // 测评结果
        $answers = $this->userDataModel->where('user_id', $userId)->select();
        if (!empty($answers[0])) {
            $answerScore = [];
            foreach ($answers as $k => $answer) {
                $factor = $this->factorModel->find($answer['question_type']);
                $answer['factor'] = $factor['title'] ?? '';
                $answerScore[] = $answer['answer_score'];
            }
            $totalScore = array_sum($answerScore);

            $setting = $this->settingModel->getInfo(1);
            $unusual = $totalScore >= $setting['warning_score'];

            $factors = $this->factorModel->where('mark', 1)->order('weight', 'desc')->select();
            $data = [];
            foreach ($factors as $factor) {
                $calcRule = json_decode($factor['calc_rule'], true);
                $factorAnswerScore = $this->calcScoreByFactor($answers, $factor['id']);
                $result = $this->calcResultByFactorScore($factorAnswerScore, $calcRule);
                $data[] = [
                    'id' => $factor['id'],
                    'title' => $factor['title'],
                    'tips' => $factor['tips'],
                    'desc' => $factor['desc'],
                    'score' => $factorAnswerScore,
                    'result' => $result['result'],
                    'result_desc' => $result['desc']
                ];
            }

            $excelData = [
                'total_score' => $totalScore,
                'is_unusual' => $unusual,
                'warning_text' => $setting['warning_text'],
                'data' => $data,
                'answers' => $answers,
                'user' => $userInfo
            ];
        } else {
            $excelData = [
                'user' => $userInfo
            ];
        }

        $dump = $this->doDump($excelData);

        return message('查询成功', true, ['url' => $dump]);
    }

    private function doDump($data) {
        $spreadsheet = new Spreadsheet();
        $worksheet   = $spreadsheet->getActiveSheet();

        $title = $data['user']['name'].'测评数据';
        $worksheet->setTitle($title);
        $worksheet->mergeCells('A1:B1');
        // 设置行高，第1行到第6行，行高为30
        for ($row = 1; $row <= 7; $row++) {
            $worksheet->getRowDimension($row)->setRowHeight(25);
        }
        $worksheet->getColumnDimension('A')->setWidth(15);
        $worksheet->getColumnDimension('B')->setWidth(25);
        $worksheet->getColumnDimension('C')->setWidth(25);
        $worksheet->getStyle('A1:D1')->applyFromArray([
            'alignment' => [
                'horizontal' => Alignment::HORIZONTAL_CENTER,
                'vertical'   => Alignment::VERTICAL_CENTER,
            ],
            'font'      => [
                'name' => '黑体',
                'bold' => true,
                'size' => 22
            ]
        ]);
        // 定义要居中的单元格
        $cells = ['A2', 'B2', 'A3', 'B3', 'A4', 'B4', 'A5', 'B5', 'A6', 'B6', 'A7', 'B7'];
        // 遍历单元格并设置居中
        foreach ($cells as $cell) {
            $worksheet->getStyle($cell)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
            $worksheet->getStyle($cell)->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
        }
        $worksheet->setCellValueByColumnAndRow(1, 1, '用户信息');
        $worksheet->setCellValueByColumnAndRow(1, 2, '宝贝姓名');
        $worksheet->setCellValueByColumnAndRow(1, 3, '宝贝性别');
        $worksheet->setCellValueByColumnAndRow(1, 4, '出生日期');
        $worksheet->setCellValueByColumnAndRow(1, 5, '宝贝年龄');
        $worksheet->setCellValueByColumnAndRow(1, 6, '联系方式');
        $worksheet->setCellValueByColumnAndRow(1, 7, '测评时间');
        $worksheet->setCellValueByColumnAndRow(2, 2, $data['user']['name']);
        $worksheet->setCellValueByColumnAndRow(2, 3, ($data['user']['gender'] == 1 ? '男' : '女'));
        $worksheet->setCellValueByColumnAndRow(2, 4, $data['user']['birth']);
        $worksheet->setCellValueByColumnAndRow(2, 5, $data['user']['age']);
        $worksheet->setCellValueByColumnAndRow(2, 6, $data['user']['phone']);
        $worksheet->setCellValueByColumnAndRow(2, 7, !empty($data['user']['finish_time']) ? date('Y-m-d H:i:s', $data['user']['finish_time']) : '');

        if (!isset($data['answers'])) {
            $worksheet->mergeCells('A8:C8');
            $worksheet->getStyle('A8:C8')->applyFromArray([
                'alignment' => [
                    'horizontal' => Alignment::HORIZONTAL_CENTER,
                    'vertical'   => Alignment::VERTICAL_CENTER,
                ],
                'font'      => [
                    'name' => '黑体',
                    'bold' => true,
                    'size' => 22,
                    'color' => ['rgb' => Color::COLOR_BLUE]
                ]
            ]);
            $worksheet->setCellValueByColumnAndRow(1, 8, '该用户未完成测评');
        } else {
            $worksheet->mergeCells('A8:C8');
            $worksheet->getStyle('A8:C8')->applyFromArray([
                'alignment' => [
                    'horizontal' => Alignment::HORIZONTAL_CENTER,
                    'vertical'   => Alignment::VERTICAL_CENTER,
                ],
                'font'      => [
                    'name' => '黑体',
                    'bold' => true,
                    'size' => 22
                ]
            ]);
            $re = '评测结果：' . ($data['is_unusual'] ? '异常' : '正常');
            $worksheet->setCellValueByColumnAndRow(1, 8, $re);
            if ($data['is_unusual']) {
                $styleArray = [
                    'font' => [
                        'color' => [
                            'rgb' => Color::COLOR_BLUE, // 使用PhpSpreadsheet的颜色常量设置颜色
                        ],
                    ],
                ];
                $worksheet->getStyle('A8')->applyFromArray($styleArray);
            }


            $firstKey = 9;
            $cols = ['A', 'B', 'C', 'D'];
            foreach ($data['data'] as $key => $datum) {
                $colIndex = $firstKey+$key;

                foreach ($cols as $col) {
                    $worksheet->getStyle($col.$colIndex)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
                    $worksheet->getStyle($col.$colIndex)->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
                }

                $worksheet->getRowDimension($colIndex)->setRowHeight(30);
                $worksheet->setCellValueByColumnAndRow(1, $colIndex, $datum['title']);
                $worksheet->setCellValueByColumnAndRow(2, $colIndex, '得分：'.$datum['score'].'分');
                $worksheet->setCellValueByColumnAndRow(3, $colIndex, '结果：'.$datum['result']);
                if ($datum['result'] == '异常') {
                    $styleArray = [
                        'font' => [
                            'color' => [
                                'rgb' => Color::COLOR_BLUE, // 使用PhpSpreadsheet的颜色常量设置颜色
                            ],
                        ],
                    ];
                    $worksheet->getStyle('A'.$colIndex.':C'.$colIndex)->applyFromArray($styleArray);
                }

            }

            // 添加一个新的工作表
            $sheet = $spreadsheet->createSheet();

            // 设置工作表的标题
            $sheet->setTitle('测评明细');

            $sheet->setCellValueByColumnAndRow(1, 1, '测评因子');
            $sheet->setCellValueByColumnAndRow(2, 1, '问题');
            $sheet->setCellValueByColumnAndRow(3, 1, '回答');
            $sheet->setCellValueByColumnAndRow(4, 1, '得分');
            $sheet->getColumnDimension('A')->setWidth(15);
            $sheet->getColumnDimension('B')->setWidth(45);
            $sheet->getColumnDimension('C')->setWidth(25);
            $sheet->getColumnDimension('C')->setWidth(15);
            $sheet->getStyle('A1:D1')->applyFromArray([
                'alignment' => [
                    'horizontal' => Alignment::HORIZONTAL_CENTER,
                    'vertical'   => Alignment::VERTICAL_CENTER,
                ],
                'font'      => [
                    'size' => 18
                ]
            ]);
            $answerFirstKey = 2;
            foreach ($data['answers'] as $ak => $answer) {
                $answerColIndex = $answerFirstKey+$ak;

                foreach ($cols as $col) {
                    // $worksheet->getStyle($col.$answerColIndex)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
                    $sheet->getStyle($col.$answerColIndex)->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
                }

                $sheet->getRowDimension($answerColIndex)->setRowHeight(30);
                $sheet->setCellValueByColumnAndRow(1, $answerColIndex, $answer['factor']);
                $sheet->setCellValueByColumnAndRow(2, $answerColIndex, $answer['question']);
                $sheet->setCellValueByColumnAndRow(3, $answerColIndex, $answer['answer_text']);
                $sheet->setCellValueByColumnAndRow(4, $answerColIndex, $answer['answer_score'].'分');
            }

        }

        $spreadsheet->setActiveSheetIndex(0);

        $writer = new Xlsx($spreadsheet);
        $writer->save('./downloads/'.date('Yhm').'-'.$data['user']['name'].'测评数据.xlsx');

        $url = DOWNLOAD_URL.'/'.date('Yhm').'-'.$data['user']['name'].'测评数据.xlsx';
        return $url;
    }
}